b1fffd
@@ -15,6 +15,7 @@
 
 import java.sql.Timestamp;
 import java.util.Calendar;
+import java.util.GregorianCalendar;
 import java.util.TimeZone;
 import java.util.concurrent.TimeUnit;
 
@@ -28,6 +29,7 @@
    static final long NANOS_PER_HOUR = TimeUnit.HOURS.toNanos(1);
    static final long NANOS_PER_MINUTE = TimeUnit.MINUTES.toNanos(1);
    static final long NANOS_PER_SECOND = TimeUnit.SECONDS.toNanos(1);
+   static final long NANOS_PER_DAY = TimeUnit.DAYS.toNanos(1);
 
    private static final ThreadLocal<Calendar> parquetGMTCalendar = new ThreadLocal<Calendar>();
    private static final ThreadLocal<Calendar> parquetLocalCalendar = new ThreadLocal<Calendar>();
@@ -48,14 +50,20 @@
private static Calendar getLocalCalendar() {
    }
 
    private static Calendar getCalendar(boolean skipConversion) {
-     return skipConversion ? getLocalCalendar() : getGMTCalendar();
+     Calendar calendar = skipConversion ? getLocalCalendar() : getGMTCalendar();
+     calendar.clear(); // Reset all fields before reusing this instance
+     return calendar;
    }
 
    public static NanoTime getNanoTime(Timestamp ts, boolean skipConversion) {
 
      Calendar calendar = getCalendar(skipConversion);
      calendar.setTime(ts);
-     JDateTime jDateTime = new JDateTime(calendar.get(Calendar.YEAR),
+     int year = calendar.get(Calendar.YEAR);
+     if (calendar.get(Calendar.ERA) == GregorianCalendar.BC) {
+       year = 1 - year;
+     }
+     JDateTime jDateTime = new JDateTime(year,
        calendar.get(Calendar.MONTH) + 1,  //java calendar index starting at 1.
        calendar.get(Calendar.DAY_OF_MONTH));
      int days = jDateTime.getJulianDayNumber();
@@ -74,13 +82,20 @@
public static Timestamp getTimestamp(NanoTime nt, boolean skipConversion) {
      int julianDay = nt.getJulianDay();
      long nanosOfDay = nt.getTimeOfDayNanos();
 
+     long remainder = nanosOfDay;
+     julianDay += remainder / NANOS_PER_DAY;
+     remainder %= NANOS_PER_DAY;
+     if (remainder < 0) {
+       remainder += NANOS_PER_DAY;
+       julianDay--;
+     }
+
      JDateTime jDateTime = new JDateTime((double) julianDay);
      Calendar calendar = getCalendar(skipConversion);
      calendar.set(Calendar.YEAR, jDateTime.getYear());
-     calendar.set(Calendar.MONTH, jDateTime.getMonth() - 1); //java calender index starting at 1.
+     calendar.set(Calendar.MONTH, jDateTime.getMonth() - 1); //java calendar index starting at 1.
      calendar.set(Calendar.DAY_OF_MONTH, jDateTime.getDay());
 
-     long remainder = nanosOfDay;
      int hour = (int) (remainder / (NANOS_PER_HOUR));
      remainder = remainder % (NANOS_PER_HOUR);
      int minutes = (int) (remainder / (NANOS_PER_MINUTE));
